package com.harisucici.jetpackbase.base;

import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.inputmethod.InputMethodManager;

import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;

import com.harisucici.jetpackbase.base.HBaseViewModel.ParameterField;
import com.harisucici.jetpackbase.view.DialogLoading;
import com.harisucici.jetpackbase.view.SnackbarUtil;
import com.zackratos.ultimatebarx.library.UltimateBarX;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;


public abstract class HBaseActivity<V extends ViewDataBinding, VM extends HBaseViewModel> extends AppCompatActivity implements IBaseView {
    protected V binding;
    protected VM viewModel;
    private int viewModelId;
    private DialogLoading dialogLoading;
    private ActivityResultLauncher<Intent> launchForResult;


    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();



    }

    public void onLaunchFourResult(ActivityResult result) {


    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        UltimateBarX.create(UltimateBarX.STATUS_BAR).bgColor(Color.WHITE).light(Configuration.UI_MODE_NIGHT_NO == (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK)).fitWindow(true).apply(this);
        UltimateBarX.create(UltimateBarX.NAVIGATION_BAR).transparent().fitWindow(false).apply(this);
        launchForResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
            if (result.getData() == null) {
                return;
            }
            onLaunchFourResult(result);
        });
        // dataBinding viewmodel
        initViewDataBinding(savedInstanceState);
        initViewObservable();
        initParam();
        registorUIChangeLiveDataCallBack();
        initData(this.getWindow().getDecorView());

    }

    @Override
    protected void onResume() {
        super.onResume();

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (binding != null) {
            binding.unbind();
        }
    }

    /**
     * 注入绑定
     */
    private void initViewDataBinding(Bundle savedInstanceState) {
        binding = DataBindingUtil.setContentView(this, initContentView(savedInstanceState));
        viewModelId = initVariableId();
        viewModel = initViewModel();
        if (viewModel == null) {
            Class modelClass;
            Type type = getClass().getGenericSuperclass();
            if (type instanceof ParameterizedType) {
                modelClass = (Class) ((ParameterizedType) type).getActualTypeArguments()[1];
            } else {
                //如果没有指定泛型参数，则默认使用BaseViewModel
                modelClass = HBaseViewModel.class;
            }
            viewModel = (VM) createViewModel(this, modelClass);
        }
        //关联ViewModel
        binding.setVariable(viewModelId, viewModel);
        //支持LiveData绑定xml，数据改变，UI自动会更新
        binding.setLifecycleOwner(this);
        //让ViewModel拥有View的生命周期感应
        getLifecycle().addObserver(viewModel);
    }

    //刷新布局
    public void refreshLayout() {
        if (viewModel != null) {
            binding.setVariable(viewModelId, viewModel);
        }
    }


    /**
     * =====================================================================
     **/
    //注册ViewModel与View的契约UI回调事件
    protected void registorUIChangeLiveDataCallBack() {
        //加载对话框显示
        viewModel.getUC().getShowDialogEvent().observe(this, title -> {
            showDialog(title);
        });

        //加载对话框消失
        viewModel.getUC().getDismissDialogEvent().observe(this, v -> {
            dismissDialog();
        });
        //snackbar 显示
        viewModel.getUC().getShowSnackEvent().observe(this, message -> {
            showSnack(message);
        });
        viewModel.getUC().getShowSnackTypeEvent().observe(this, message -> {
            String[] msg = message.split("&&");
            showSnack(msg[0], Integer.parseInt(msg[1]));
        });
        //跳入新页面
        viewModel.getUC().getStartActivityEvent().observe(this, params -> {
            Class<?> clz = (Class<?>) params.get(ParameterField.CLASS);
            Bundle bundle = (Bundle) params.get(ParameterField.BUNDLE);
            startActivity(clz, bundle);
        });
        //跳入ContainerActivity
        viewModel.getUC().getStartContainerActivityEvent().observe(this, params -> {
            String canonicalName = (String) params.get(ParameterField.CANONICAL_NAME);
            Bundle bundle = (Bundle) params.get(ParameterField.BUNDLE);
            startContainerActivity(canonicalName, bundle);
        });

        //跳入NavActivity
        viewModel.getUC().getStartNavActivityEvent().observe(this, params -> {
            int navigationId = (Integer) params.get(ParameterField.NAVIGATION_ID);
            Bundle bundle = (Bundle) params.get(ParameterField.BUNDLE);
            startNavActivity(navigationId, bundle);
        });
        //Activity4Result
        viewModel.getUC().getStartActivity4ResultEvent().observe(this, params -> {
            Class<?> clz = (Class<?>) params.get(ParameterField.CLASS);
            Bundle bundle = (Bundle) params.get(ParameterField.BUNDLE);
            startActivity4Result(clz, bundle);
        });
        //关闭界面
        viewModel.getUC().getFinishEvent().observe(this, v -> finish());
        //关闭上一层
        viewModel.getUC().getOnBackPressedEvent().observe(this, v -> onBackPressed());
    }


    /**
     * 跳转页面
     *
     * @param clz 所跳转的目的Activity类
     */
    public void startActivity(Class<?> clz) {
        startActivity(new Intent(this, clz));
    }

    /**
     * 跳转页面
     *
     * @param clz    所跳转的目的Activity类
     * @param bundle 跳转所携带的信息
     */
    public void startActivity(Class<?> clz, Bundle bundle) {
        Intent intent = new Intent(this, clz);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        startActivity(intent);
    }

    /**
     * 跳转页面带回数据
     *
     * @param clz 所跳转的目的Activity类
     */
    public void startActivity4Result(Class<?> clz) {
        launchForResult.launch(new Intent(this, clz));
    }

    /**
     * 跳转页面带回数据
     *
     * @param clz    所跳转的目的Activity类
     * @param bundle 跳转所携带的信息
     */
    public void startActivity4Result(Class<?> clz, Bundle bundle) {
        Intent intent = new Intent(this, clz);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        launchForResult.launch(intent);
    }

    /**
     * 跳转容器页面
     *
     * @param canonicalName 规范名 : Fragment.class.getCanonicalName()
     */
    public void startContainerActivity(String canonicalName) {
        startContainerActivity(canonicalName, null);
    }

    /**
     * 跳转容器页面
     *
     * @param canonicalName 规范名 : Fragment.class.getCanonicalName()
     * @param bundle        跳转所携带的信息
     */
    public void startContainerActivity(String canonicalName, Bundle bundle) {
        Intent intent = new Intent(this, ContainerActivity.class);
        intent.putExtra(ContainerActivity.FRAGMENT, canonicalName);
        if (bundle != null) {
            intent.putExtra(ContainerActivity.BUNDLE, bundle);
        }
        startActivity(intent);
    }

    /**
     * 跳转Navigation页面
     *
     * @param navId 规范名 : R.navigation.navId
     */
    public void startNavActivity(int navId) {
        Intent intent = new Intent(this, NavigationActivity.class);
        intent.putExtra(NavigationActivity.NAVID, navId);
        startActivity(intent);
    }


    /**
     * 跳转Navigation页面
     *
     * @param navId  规范名 : R.navigation.navId
     * @param bundle 跳转所携带的信息
     */
    public void startNavActivity(int navId, Bundle bundle) {
        Intent intent = new Intent(this, NavigationActivity.class);
        intent.putExtra(NavigationActivity.NAVID, navId);
        if (bundle != null) {
            intent.putExtra(NavigationActivity.BUNDLE, bundle);
        }
        startActivity(intent);
    }

    /**
     * =====================================================================
     **/
    @Override
    public void initParam() {

    }

    /**
     * 初始化根布局
     *
     * @return 布局layout的id
     */
    public abstract int initContentView(Bundle savedInstanceState);

    /**
     * 初始化ViewModel的id
     *
     * @return BR的id
     */
    public abstract int initVariableId();

    /**
     * 初始化ViewModel
     *
     * @return 继承BaseViewModel的ViewModel
     */
    public VM initViewModel() {
        return null;
    }

    @Override
    public void initData(View v) {

    }

    @Override
    public void initViewObservable() {

    }

    /**
     * 创建ViewModel
     *
     * @param cls
     * @param <T>
     * @return
     */
    public <T extends ViewModel> T createViewModel(AppCompatActivity activity, Class<T> cls) {
        return new ViewModelProvider(activity, new ViewModelProvider.AndroidViewModelFactory(getApplication())).get(cls);
    }

    @Override
    public void initViewModelOwner() {
        //无用的方法
    }

    public void showDialog(String title) {
        if (dialogLoading == null) {
            dialogLoading = DialogLoading.newInstance(title);

        }
        dialogLoading.show(getSupportFragmentManager(), DialogLoading.TAG);
    }

    public void dismissDialog() {
        if (dialogLoading != null) {
            dialogLoading.dismiss();

        }
        dialogLoading = null;
    }


    public void showSnack(@NonNull String message) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm != null) {
            imm.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), 0);
        }
        SnackbarUtil.showBarShortTime(findViewById(android.R.id.content), message, SnackbarUtil.INFO);
    }

    public void showSnack(@NonNull String message, int type) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm != null) {
            imm.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), 0);
        }
        SnackbarUtil.showBarShortTime(findViewById(android.R.id.content), message, type);
    }

}
